﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Threading.Tasks;
using Elderos.Highlight.Search;
using Elderos.Ontology;
using Elderos.Utils.Extensions;
using Elderos.Utils.Logging;

namespace Elderos.Highlight.Rules
{
    [RankingRule("Area", RuleType.SelfInfo)]
    public class RuleArea : RankingRule
    {
        public RuleArea(IOntologyData ontology) : base(ontology) {}

        #region Overrides of RankingRule

        protected async override Task<Dictionary<TextEntity, IRuleResult>> InnerRank(HighlightResult highlightResult)
        {
            var result = new Dictionary<TextEntity, IRuleResult>();

            var entityAreas = new Dictionary<int, double>();
            int attid = Ontology.Attributes.First(x => x.Name == "/location/location/area").ID;
            int[] entityids = highlightResult.Positions.SelectMany(x => x.EntitiesFlattened)
                                               .Select(x => x.EntityID)
                                               .Distinct()
                                               .ToArray();

            var attValues = await Ontology.GetAttValuesAsync(new[] {attid}, entityids);

            var areas = attValues
                .Where(x => x.AttID == attid && entityids.Contains(x.EntityID))
                .Select(x => new {x.EntityID, Area = x.Value })
                .ToArray();
            foreach (var area in areas)
            {
                if (!entityAreas.ContainsKey(area.EntityID))
                {
                    double areaDouble;
                    if (!double.TryParse(area.Area, NumberStyles.Float, CultureInfo.InvariantCulture, out areaDouble))
                    {
                        Logger.Error("Invalid area attribute value: " + area.Area);
                        continue;
                    }
                    entityAreas.Add(area.EntityID, areaDouble);
                }
            }
            

            foreach (TextEntity textEntity in highlightResult.Positions.SelectMany(x => x.EntitiesFlattened))
            {
                if (!entityAreas.ContainsKey(textEntity.EntityID)) 
                    continue;
                if (entityAreas[textEntity.EntityID] <= Math.E)
                    continue;
                double coef = entityAreas[textEntity.EntityID];
                if (coef <= 0) continue;
                coef = Math.Log10(coef);
                result.Add(textEntity, new ContiniousResult(Name, coef));
            }
            return result;
        }

        public override IRuleResult EmptyResult
        {
            get { return new ContiniousResult(Name, 0); }
        }

        #endregion
    }
}
